package com.springBoot.springBootSysCore.modules.services;

import com.springBoot.springBootSysCore.common.third.sms.AliSms;
import com.springBoot.springBootSysCore.common.utils.CacheUtils;
import com.springBoot.springBootSysCore.common.utils.FileUtil;
import com.springBoot.springBootSysCore.common.utils.StringUtils;
import com.springBoot.springBootSysCore.common.utils.encoding.Encodes;
import com.springBoot.springBootSysCore.common.utils.returnUtil.CodeEnum;
import com.springBoot.springBootSysCore.common.utils.returnUtil.ResultJsonFormat;
import com.springBoot.springBootSysCore.modules.entity.system.SysUser;
import com.springBoot.springBootSysCore.modules.entity.utils.UserUtils;
import com.springBoot.springBootSysCore.modules.enums.base.UserTypeEnum;
import com.springBoot.springBootSysCore.modules.repository.system.SysRoleRepository;
import com.springBoot.springBootSysCore.modules.repository.system.SysUserRepository;
import com.springBoot.springBootSysCore.modules.shiro.SystemAuthorizingRealm.Principal;
import com.springBoot.springBootSysCore.modules.shiro.UsernamePasswordToken;
import com.springBoot.springBootSysCore.servlet.ValidateCodeServlet;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.subject.Subject;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Isolation;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

import javax.servlet.http.HttpServletRequest;
import java.util.Date;
import java.util.Map;

@Service
public class SysAppLoginServiceImpl implements SysAppLoginService{
	
	@Value("${productSalt}")
	private String productSalt;
	@Autowired
	private SysUserRepository sysUserRepository;
	@Autowired
	private SysRoleRepository sysRoleRepository;
	/**
	 * 获取系统时间戳
	 */
	@Override
	public Map<String, Object> getCurSysTimestamp(String phone) {
		ResultJsonFormat rj = new ResultJsonFormat(CodeEnum.SUCCESS.value());
		if(StringUtils.isEmpty(phone)){
			rj.setFlag(CodeEnum.Failed.value());
			rj.setMsg("电话不能为空");
			return rj.convertResultJsonForData();
		}
		Long ts = System.currentTimeMillis();
		CacheUtils.put("timestampCache", phone+"timestamp",ts);
		rj.setMsg(Encodes.getMD5Str((phone+ts+productSalt)));
		rj.setData(ts);
		return rj.convertResultJsonForData();
	}
	/**
	 * 获取验证码
	 * @throws Exception 
	 */
	@Override
	public Map<String, Object> getMsgCode(String phone, String msgCodeType, String secret) throws Exception {
		//判断加密是否正确  加密方法:用户账号+接口返回时间戳+加密盐 进行md5
		ResultJsonFormat rj = new ResultJsonFormat(CodeEnum.Failed.value());
		Object e= CacheUtils.get("timestampCache",phone+"timestamp");
		if(e==null||e==""){
			rj.setMsg("获取验证码超时，请刷新页面重试");
			return rj.convertResultJsonForData();
		}
		if(!secret.equals(Encodes.getMD5Str((phone+e+productSalt)))){
			rj.setMsg("获取验证码失败，请重试");
			return rj.convertResultJsonForData();
		}
		CacheUtils.remove("timestampCache",phone+"timestamp");
		SysUser user = UserUtils.getByAccount(phone);
		if(!"login".equals(msgCodeType)){
			if("register".equals(msgCodeType)){//注册
				if(user!=null){
					rj.setMsg("当前用户已存在");
					return rj.convertResultJsonForData();
				}
			}else if("forgetPwd".equals(msgCodeType)){//忘记密码
				if(user==null){
					rj.setMsg("当前用户不存在");
					return rj.convertResultJsonForData();
				}
			}
		}
		String random = StringUtils.randomSix();
//		MeiSheng.sendSMS(phone, random);
		AliSms.sendSms(phone, random);
		CacheUtils.put("msgCodeCache",phone+"msgCode",random);
		rj.setMsg("获取验证码成功");
		rj.setFlag(CodeEnum.SUCCESS.value());
		rj.setData(random);
		return rj.convertResultJsonForData();
	}
	/**
	 * 注册用户
	 */
	@Override
	@Transactional(propagation = Propagation.REQUIRED,isolation = Isolation.DEFAULT,timeout=36000,rollbackFor=Exception.class)
	public Map<String, Object> register(String phone, String msgCode, String passWord) {
		ResultJsonFormat rj = new ResultJsonFormat(CodeEnum.Failed.value());
		SysUser user = UserUtils.getByAccount(phone);
		if(user!=null){
			rj.setMsg("当前用户已被注册");
			return rj.convertResultJsonForData();
		}
		//校验验证码
		Object e= CacheUtils.get("msgCodeCache",phone+"msgCode");
		if(e==null||e==""){
			rj.setMsg("验证码已过期,请重新获取验证码");
			return rj.convertResultJsonForData();
		}
		if(!msgCode.equals(e)){
			rj.setMsg("验证码错误");
			return rj.convertResultJsonForData();
		}
		CacheUtils.remove("msgCodeCache",phone+"msgCode");
		user = new SysUser();
		user.setPhone(phone);
		user.setAccount(phone);
		user.setNickName(phone);
		user.setSex(1);
		user.setCreateDate(new Date());
		user.setPassword(SystemService.entryptPassword(passWord));
		user.setUserType(UserTypeEnum.NOMAL.getVal());
		user.setDefalutRole(sysRoleRepository.findByName("普通用户"));
		sysUserRepository.save(user);
		rj.setFlag(CodeEnum.SUCCESS.value());
		rj.setMsg("注册成功");
		return rj.convertResultJsonForData();
	}
	@Override
	@Transactional
	public Map<String, Object> updateForgetPwd(String phone, String msgCode, String passWord) {
		ResultJsonFormat rj = new ResultJsonFormat(CodeEnum.Failed.value());
		//校验验证码
		Object e= CacheUtils.get("msgCodeCache",phone+"msgCode");
		if(e==null||e==""){
			rj.setMsg("验证码已过期,请重新获取验证码");
			return rj.convertResultJsonForData();
		}
		if(!msgCode.equals(e)){
			rj.setMsg("验证码错误");
			return rj.convertResultJsonForData();
		}
		SysUser sysUser = sysUserRepository.findByAccount(phone);
		sysUser.setPassword(SystemService.entryptPassword(passWord));

		CacheUtils.remove("msgCodeCache",phone+"msgCode");
		CacheUtils.remove(UserUtils.USER_CACHE);
//		CacheUtils.remove("loginFailMap");
		CacheUtils.remove("passwordRetryCache",sysUser.getAccount());

		rj.setFlag(CodeEnum.SUCCESS.value());
		rj.setMsg("修改成功");
		return rj.convertResultJsonForData();
	}
	@Override
	@Transactional
	public Map<String, Object> login(String phone, String msgCode,String passWord) {
		ResultJsonFormat rj = new ResultJsonFormat(CodeEnum.Failed.value());
		//校验验证码
//		Object e= CacheUtils.get("msgCodeCache",phone+"msgCode");
//		if(e==null||e==""){
//			rj.setMsg("验证码已过期,请重新获取验证码");
//			return rj.convertResultJsonForData();
//		}
//		if(!msgCode.equals(e)){
//			rj.setMsg("验证码错误");
//			return rj.convertResultJsonForData();
//		}
//		CacheUtils.remove("msgCodeCache",phone+"msgCode");
		char[] password = (passWord+"").toCharArray();
		String username = phone;
		UsernamePasswordToken token = new UsernamePasswordToken(username,password);
    	Subject currentUser = SecurityUtils.getSubject();
    	try {
    		 currentUser.login(token);
		} catch (Exception e1) {
			rj.setFlag(CodeEnum.Failed.value());
			rj.setMsg("登录失败");
			return rj.convertResultJsonForData();
		}
		rj.setFlag(CodeEnum.SUCCESS.value());
		rj.setData(UserUtils.getByAccount(phone));
		rj.setMsg("登录成功");

		return rj.convertResultJson();
	}
	@Override
	public Map<String, Object> uploadPhoto(String userId, HttpServletRequest request) {
		ResultJsonFormat rj = new ResultJsonFormat(CodeEnum.Failed.value());
		Map<String,String> fileMap = FileUtil.upLoadFile("/userfiles/userPhoto/", request);
		if(fileMap != null && fileMap.size() >= 1){
			String imgPath = fileMap.get("headImgFile");
			SysUser sysUser = sysUserRepository.getOne(userId);
			if(sysUser != null) {
				FileUtil.delFileByPath(request, sysUser.getPhoto());
				sysUser.setPhoto(imgPath);
				rj.setData(imgPath);
			}else{
				rj.setMsg("用户不存在");
				return rj.convertResultJsonForData();
			}
		}else{
			rj.setMsg("上传失败");
			return rj.convertResultJsonForData();
		}
		rj.setFlag(CodeEnum.SUCCESS.value());
		return rj.convertResultJsonForData();
	}
	@Override
	public Map<String, Object> validateCode(String code) {
		ResultJsonFormat rj = new ResultJsonFormat(CodeEnum.Failed.value());
		String code1 = (String) SecurityUtils.getSubject().getSession().getAttribute(ValidateCodeServlet.VALIDATE_CODE);
		if(code.equalsIgnoreCase(code1)){
			rj.setFlag(CodeEnum.SUCCESS.value());
		}else{
			rj.setMsg("验证码不正确");
		}
		return rj.convertResultJsonForData();
	}
	@Override
	public Map<String, Object> loginOut() {
		ResultJsonFormat rj = new ResultJsonFormat("退出成功", CodeEnum.SUCCESS.value());
		System.out.println(SecurityUtils.getSubject().getPrincipal()+" 退出登录");
		SecurityUtils.getSubject().logout();
		return rj.convertResultJsonForData();
	}
	
	
}
